﻿Imports ASAP.TiposDatosSTE
Imports System.Data.Objects

Public Class Agente

    Public Class EstadisticasRonda
        Public Ronda As Integer
        Public TotalPendientes As Integer
        Public TotalCorrectas As Integer
        Public TotalIncorrectas As Integer
    End Class

    Private Sub New()

    End Sub

    Public Enum TipoPregunta
        Vocabulario
        PhrasalVerb
        ExpresionSemana
        Numeros
        GimnasiaVerbal
        Todo
    End Enum

    Public Shared Sub PreguntaEjercicio(ByVal nivel As String, _
                                        ByVal tipoEjercicio As String, _
                                        ByVal TituloTeoria As String, _
                                        ByRef ejercicioSiguiente As Ejercicio,
                                        ByRef estadRonda As EstadisticasRonda)


        Using contexto As New TiposDatosSTE.ContenedorEntidades

            'Consulta todos los ejercicios con sus resultados
            Dim qryEjercicios As System.Linq.IQueryable(Of Ejercicio)

            If tipoEjercicio = "Vocabulario" Then
                qryEjercicios = _
                    From e In contexto.Ejercicios.Include("Resultados")
                    Where e.EsVocabulario And e.Nivel = nivel
            ElseIf tipoEjercicio = "Todo" Then
                qryEjercicios = _
                    From e In contexto.Ejercicios.Include("Resultados")
                    Where e.Nivel = nivel
            Else
                qryEjercicios = _
                    From e In contexto.Ejercicios.Include("Resultados")
                    Where e.TipoEjercicio = tipoEjercicio And e.Nivel = nivel
            End If

            'Calcula la ronda
            Dim ronda As Integer
            ronda = CalculaRonda(qryEjercicios)

            'Consulta todos los ejercicios contestados ronda - 1 veces.
            Dim qry = From e In qryEjercicios
                      Where e.Resultados.Count = ronda - 1 And e.Nivel = nivel

            'Crea un coleccion con los ejercicios candidatos a ser preguntados
            'con sólo las únicas no correctas.
            Dim EjerciciosCandidatos As New List(Of Ejercicio)
            For Each ejer As Ejercicio In qry

                Dim qryResultadosOrdenadosFecha = From r As Resultado In ejer.Resultados
                                                  Order By r.Fecha Ascending
                                                  Select r
                If qryResultadosOrdenadosFecha.Count = 0 Then
                    EjerciciosCandidatos.Add(ejer)
                Else
                    Dim ultimoResultado As Resultado = qryResultadosOrdenadosFecha.ToList(qryResultadosOrdenadosFecha.Count - 1)

                    If ultimoResultado.Correcto = False Then
                        'If ultimoResultado.TituloTeoria = "Todo" Then
                        EjerciciosCandidatos.Add(ejer)
                        'ElseIf ultimoResultado.TituloTeoria = TituloTeoria Then
                        '    EjerciciosCandidatos.Add(ejer)
                        'End If
                End If
                End If


            Next

            'Propone un ejercicio al azar.
            Dim Random As New Random()
            If EjerciciosCandidatos.Count > 0 Then
                ejercicioSiguiente = EjerciciosCandidatos(Random.Next(0, EjerciciosCandidatos.Count - 1))
                contexto.Ejercicios.Detach(ejercicioSiguiente)
            Else
                Throw New Exception("No hay más preguntas")
            End If

            estadRonda = DameEstadisticasRonda(ronda, qryEjercicios)
        End Using

    End Sub

    'Private Shared Function CalculaRonda(ByVal l As System.Linq.IQueryable(Of Ejercicio)) As Integer

    '    Dim minRespuestas As Integer = Integer.MaxValue
    '    Dim respuestasEjer As Integer = 0

    '    For Each ejer As Ejercicio In l
    '        If ejer.Resultados Is Nothing Then
    '            Return 1
    '        Else
    '            respuestasEjer = ejer.Resultados.Count

    '            If respuestasEjer < minRespuestas Then
    '                minRespuestas = respuestasEjer
    '            End If

    '        End If
    '        respuestasEjer = 0
    '    Next

    '    Return minRespuestas + 1

    'End Function

    Private Shared Function CalculaRonda(ByVal l As System.Linq.IQueryable(Of Ejercicio)) As Integer


        Dim minRondaEjerIncorrecto As Integer = Integer.MaxValue
        Dim maxRondaEjerTotal As Integer = 0

        For Each ejer As Ejercicio In l
            If ejer.Resultados.Count = 0 Then
                Return 1
            Else

                If ejer.Resultados.Count > maxRondaEjerTotal Then
                    maxRondaEjerTotal = ejer.Resultados.Count
                End If

                If Not ejer.Resultados(ejer.Resultados.Count - 1).Correcto Then
                    If minRondaEjerIncorrecto > ejer.Resultados.Count Then
                        minRondaEjerIncorrecto = ejer.Resultados.Count
                    End If
                End If

            End If

        Next

        If minRondaEjerIncorrecto < maxRondaEjerTotal Then
            Return minRondaEjerIncorrecto + 1
        Else
            Return maxRondaEjerTotal + 1
        End If

    End Function

    Private Shared Function DameEstadisticasRonda(ByVal ronda As Integer,
                                                  ByVal qryEjercicios As System.Linq.IQueryable(Of Ejercicio)) As EstadisticasRonda
        Dim est As New EstadisticasRonda

        est.Ronda = ronda

        For Each ejer As Ejercicio In qryEjercicios

            Dim qryResultados = From r As Resultado In ejer.Resultados
                                Order By r.Fecha Ascending

            If qryResultados.Count < ronda Then
                If qryResultados.Count = 0 Then
                    est.TotalPendientes = est.TotalPendientes + 1
                Else
                    If qryResultados(ronda - 2) IsNot Nothing Then
                        If qryResultados(ronda - 2).Correcto = False Then
                            est.TotalPendientes = est.TotalPendientes + 1
                        End If
                    End If
                End If
            Else
                If qryResultados(ronda - 1).Correcto Then
                    est.TotalCorrectas = est.TotalCorrectas + 1
                Else
                    est.TotalIncorrectas = est.TotalIncorrectas + 1
                End If
            End If

        Next

        Return est

    End Function



    Public Shared Function DameTeorias() As List(Of Teoria)

        Using contexto As New TiposDatosSTE.ContenedorEntidades

            DameTeorias = contexto.Teorias.ToList

        End Using

    End Function

    Public Shared Sub ActualizaEjercicioResultado(ByVal ejer As Ejercicio)

        Using contexto As New TiposDatosSTE.ContenedorEntidades

            contexto.Ejercicios.Attach(ejer)
            contexto.ObjectStateManager.ChangeObjectState(ejer, System.Data.EntityState.Modified)

            Dim q = From r In ejer.Resultados
            Order By r.Fecha Descending

            Dim res As Resultado = q.First

            contexto.ObjectStateManager.ChangeObjectState(res, System.Data.EntityState.Added)

            contexto.SaveChanges()
            contexto.AcceptAllChanges()
        End Using

    End Sub

    Public Shared Sub ActualizaTeoria(ByVal teo As Teoria)
        Using contexto As New TiposDatosSTE.ContenedorEntidades

            Dim q = From t In contexto.Teorias
                    Where t.TituloTeoria = teo.TituloTeoria

            Dim teoBD As Teoria = q.First

            teoBD.Documento = teo.Documento

            contexto.SaveChanges()

        End Using
    End Sub

    Public Shared Function DameAudio(ByVal ejer As Ejercicio) As Byte()

        Using contexto As New TiposDatosSTE.ContenedorEntidades

            Dim q = From l As Leccion In contexto.Lecciones
                          Where l.Nivel = ejer.Nivel And
                          l.Tema = ejer.Tema And
                          l.TipoEjercicio = ejer.TipoEjercicio And
                          l.Volumen = ejer.Volumen

            Dim lec As Leccion = q.First
            If lec IsNot Nothing Then
                DameAudio = lec.Audio
            Else
                DameAudio = Nothing
            End If

        End Using

    End Function

    Public Shared Function DameAudio(ByVal lec As Leccion) As Byte()

        Using contexto As New TiposDatosSTE.ContenedorEntidades

            Dim q = From l As Leccion In contexto.Lecciones
                          Where l.Nivel = lec.Nivel And
                          l.Tema = lec.Tema And
                          l.TipoEjercicio = lec.TipoEjercicio And
                          l.Volumen = lec.Volumen

            Dim Primeraleccion As Leccion = q.First
            If Primeraleccion IsNot Nothing Then
                DameAudio = Primeraleccion.Audio
            Else
                DameAudio = Nothing
            End If

        End Using

    End Function

    Public Shared Function DameImagenesLibro(ByVal ejer As Ejercicio) As Byte()


        Dim imagenes As New List(Of Byte())

        Using contexto As New TiposDatosSTE.ContenedorEntidades

            Dim q = From l As Leccion In contexto.Lecciones.Include("Paginas")
                          Where l.Nivel = ejer.Nivel And
                          l.Tema = ejer.Tema And
                          l.TipoEjercicio = ejer.TipoEjercicio And
                          l.Volumen = ejer.Volumen

            Dim lec As Leccion = q.First

            For Each pagina As Pagina In lec.Paginas
                imagenes.Add(pagina.Imagen)
            Next

        End Using

        Return TrataTif.ConvertirAMultiTiff(imagenes)

    End Function

    Public Shared Sub DameEstadisticas(ByVal nivel As String, _
                                       ByRef TotalPreguntas As Integer, _
                                       ByRef TotalPreguntasContestadas As Integer, _
                                       ByRef EstadisticasTotales As EstadResultado, _
                                       ByRef EstadisticasSecciones As Dictionary(Of String, EstadResultado), _
                                       ByRef EstadisticasLecciones As Dictionary(Of EstadClaveLeccion, EstadResultado), _
                                       ByRef EstadisticasLibro As Dictionary(Of EstadClaveLibro, EstadResultado), _
                                       ByRef EstadisticasTeorias As Dictionary(Of String, EstadResultado))

        Estadisticas.DameEstadisticas(nivel, TotalPreguntas, TotalPreguntasContestadas, _
                         EstadisticasTotales, EstadisticasSecciones, _
                         EstadisticasLecciones, EstadisticasLibro, EstadisticasTeorias)

    End Sub


    Public Class EjerRevisionRonda

        Public TituloTeoria As String

        Private pVolumen As Integer
        Public Property Volumen() As Integer
            Get
                Return pVolumen
            End Get
            Set(ByVal value As Integer)
                pVolumen = value
            End Set
        End Property

        Private pTema As String
        Public Property Tema() As String
            Get
                Return pTema
            End Get
            Set(ByVal value As String)
                pTema = value
            End Set
        End Property


        Private pCastellano As String
        Public Property Castellano() As String
            Get
                Return pCastellano
            End Get
            Set(ByVal value As String)
                pCastellano = value
            End Set
        End Property

        Private pRespuesta As String
        Public Property Respuesta() As String
            Get
                Return pRespuesta
            End Get
            Set(ByVal value As String)
                pRespuesta = value
            End Set
        End Property

        Private pIngles As String
        Public Property Ingles() As String
            Get
                Return pIngles
            End Get
            Set(ByVal value As String)
                pIngles = value
            End Set
        End Property


        Private pTipoEjercicio As String
        Public Property TipoEjer() As String
            Get
                Return pTipoEjercicio
            End Get
            Set(ByVal value As String)
                pTipoEjercicio = value
            End Set
        End Property

    End Class


    Public Shared Function AnalisisRonda(Nivel As String, Ronda As Integer) _
        As Generic.Dictionary(Of String, List(Of EjerRevisionRonda))

        Dim hash As New Generic.Dictionary(Of String, List(Of EjerRevisionRonda))

        Using contexto As New TiposDatosSTE.ContenedorEntidades

            'Consulta todos los ejercicios del nivel
            Dim ejers = _
                From ejer In contexto.Ejercicios.Include("Resultados")
                Where ejer.Nivel = Nivel
                Select ejer


            'Calcula los resultados incorrectos de la ronda
            Dim resultadosIncorrectosRonda As New List(Of EjerRevisionRonda)

            For Each e As Ejercicio In ejers

                Dim resultadosOrdenados = _
                    From result In e.Resultados
                    Order By result.Fecha Ascending
                    Select result


                If resultadosOrdenados.Count > 0 AndAlso resultadosOrdenados.Count <= Ronda Then

                    Dim r As Resultado = resultadosOrdenados.ToList(Ronda - 1)

                    If Not r.Correcto Then

                        Dim eRevision As New EjerRevisionRonda

                        eRevision.Castellano = r.Ejercicio.Castellano
                        eRevision.Ingles = r.Ejercicio.Ingles
                        eRevision.Respuesta = r.Ingles

                        eRevision.Tema = r.Tema
                        eRevision.TituloTeoria = r.TituloTeoria
                        eRevision.TipoEjer = r.TipoEjercicio
                        eRevision.Volumen = r.Volumen

                        resultadosIncorrectosRonda.Add(eRevision)

                    End If

                End If

            Next

            Dim incorrectosAgrupadosPorTeoria = _
            From res In resultadosIncorrectosRonda
            Group res By res.TituloTeoria Into g = Group _
            Select New With {.TituloTeoria = TituloTeoria, .ResultadoLine = g}

            Dim RevisionRonda As String = ""

            For Each resGroup In incorrectosAgrupadosPorTeoria

                If Not hash.ContainsKey(resGroup.TituloTeoria) Then
                    hash.Add(resGroup.TituloTeoria, New List(Of EjerRevisionRonda))
                End If

                For Each res In resGroup.ResultadoLine
                    hash.Item(resGroup.TituloTeoria).Add(res)
                Next

            Next

        End Using

        Return hash

    End Function


    'Public Sub EliminaResultadosDuplicados()

    '    Using contexto As New TiposDatosSTE.ContenedorEntidades

    '        For Each r1 As Resultado In contexto.Resultados
    '            For Each r2 As Resultado In contexto.Resultados

    '                If r2.Nivel = r1.Nivel And
    '                    r2.Volumen = r1.Volumen And
    '                    r2.TipoEjercicio = r1.TipoEjercicio And
    '                    r2.Tema = r1.Tema And
    '                    r2.NumEjercicio = r1.NumEjercicio And
    '                    r2.Fecha <> r1.Fecha Then

    '                    contexto.Resultados.DeleteObject(r2)

    '                End If

    '            Next
    '        Next

    '        contexto.SaveChanges()

    '    End Using

    'End Sub

End Class
